package cn.tonyandmoney.warescanapp.socket

import android.content.Context
import com.codebutler.android_websockets.WebSocketClient
import com.dhh.rxlifecycle2.RxLifecycle
import io.reactivex.Observable
import io.reactivex.schedulers.Schedulers
import io.reactivex.subjects.PublishSubject
import org.jetbrains.anko.AnkoLogger
import org.jetbrains.anko.error
import org.jetbrains.anko.info
import java.net.URI

/**
 * Created by niantuo on 2018/2/27.
 * 这个更rxJava 结合
 */
class RxWebSocketUtils : AnkoLogger {

    private val mClient = HashMap<String, WebSocketClient>()
    private val mBus = PublishSubject.create<RxSocketEvent>()

    /**
     * 注册回调
     */
    fun register(): Observable<RxSocketEvent> {
        return mBus.ofType(RxSocketEvent::class.java)
    }

    /**
     * 连接，如果出错，重试5次
     */
    fun connect(url: String, content: Context) {
        val client = WebSocketClient(URI.create(url), WebSocketHandler(url, mBus), emptyList())
        mClient[url] = client
        Observable.create<Int> {
            info("开始连接： $url")
            register().compose(RxLifecycle.with(content).bindOnDestroy())
                    .subscribe(RxWebSocketConnectConsumer(it))
            client.connect()
        }.compose(RxLifecycle.with(content).bindOnDestroy())
                .retryWhen(RetryWithDelay(5, 5000))
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .subscribe(RxWebSocketObserver())

    }

    fun send(msg: String) {
        if (mClient.isEmpty()) {
            error("无webSocket 连接")
        } else {
            Schedulers.io().scheduleDirect {
                val url = mClient.keys.first()
                val client = mClient[url]!!
                val listener = client.listener as WebSocketHandler
                if (listener.isConnecting()) {
                    client.send(msg)
                    mBus.onNext(RxSocketEvent(url, RxSocketEvent.CODE_SEND_SUCCESS, msg))
                } else {
                    mBus.onNext(RxSocketEvent(url, RxSocketEvent.CODE_SEND_FAILED, "该客户端未连接。"))
                }
            }
        }
    }

    /**
     * 停止连接
     */
    fun stop() {
        mClient.values.forEach { it.disconnect() }
    }


}